# 新闻评论，详情页
from . import news_blue
from flask import render_template, current_app, jsonify, g, abort, request
from first_info.models import User, News, Comment,CommentLike
from first_info import constants, response_code, db
from first_info.utils.comment import user_login_data


# 关注与取消关注
@news_blue.route('/followed_user', methods=['POST'])
@user_login_data
def followed_user():
    # 获取当前登陆用户
    user = g.user
    if not user:
        return jsonify(errno=response_code.RET.SESSIONERR, errmag='用户未登陆')
    # 1.接收参数（新闻的作者，关注或者取消参数）
    user_id = request.json.get('user_id')
    action = request.json.get('action')
    # 2.校验参数
    if not all([user_id, action]):
        return jsonify(errno=response_code.RET.PARAMERR, errmag='参数不全')
    if action not in ('follow', 'unfollow'):
        return jsonify(errno=response_code.RET.PARAMERR, errmag='参数错误')
    # 3.核对相关信息
    # 通过用户id查询该作者
    try:
        news_author = User.query.get(user_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=response_code.RET.DBERR, errmag='查询数据库失败')
    if not news_author:
        return jsonify(errno=response_code.RET.DATAERR, errmag='无此作者')
    if action == 'follow':
        if news_author not in user.followed:
            user.followed.append(news_author)
        else:
            return jsonify(errno=response_code.RET.PARAMERR, errmag='已关注')
    else:
        if news_author in user.followed:
            user.followed.remove(news_author)
        else:
            return jsonify(errno=response_code.RET.PARAMERR, errmag='未关注')
    # 关于数据库的操作
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=response_code.RET.DBERR, errmag='数据库操作失败')
    return jsonify(errno=response_code.RET.OK, errmag='成功')




# 评论的点赞功能
@news_blue.route('/comment_like', methods=['POST'])
@user_login_data
def comment_like():
    user = g.user
    if not user:
        return jsonify(errno=response_code.RET.SESSIONERR, errmag='用户未登陆')
    # 2.获取参数
    comment_id = request.json.get('comment_id')
    action = request.json.get('action')
    # 3.校验参数
    if not all([comment_id, action]):
        return jsonify(errno=response_code.RET.PARAMERR, errmag='参数不全')
    if action not in ('add', 'remove'):
        return jsonify(errno=response_code.RET.PARAMERR, errmag='参数不正确')
    # 4.查询此条评论是否存在
    try:
        comment = Comment.query.get(comment_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=response_code.RET.DBERR, errmag='查询数据库错误')
    if not comment:
        return jsonify(errno=response_code.RET.NODATA, errmag='没有此条评论')
    comment_like_model = CommentLike.query.filter(user.id == CommentLike.user_id,
                                                  comment.id == CommentLike.comment_id).first()

    if action == 'add':
        if not comment_like_model:
            # 创建点赞对象
            comment_like_info = CommentLike()
            comment_like_info.comment_id = comment.id
            comment_like_info.user_id = user.id

            db.session.add(comment_like_info)
            # 累加点赞数
            comment.like_count += 1

    else:
        # 取消点赞
        if comment_like_model:
            db.session.delete(comment_like_model)
            # 减少点赞数
            comment.like_count -= 1
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=response_code.RET.DBERR, errmag='数据操作错误')

    # 5.响应处理结果
    return jsonify(errno=response_code.RET.OK, errmag='数据操作成功')


# 评论与回复评论
@news_blue.route('/news_comment', methods=['POST'])
@user_login_data
def news_comment():
    # 1.获取 用户是否登陆
    user = g.user

    if not user:
        return jsonify(errno=response_code.RET.SESSIONERR, errmag='用户未登陆')
    # 2.获取参数
    news_id = request.json.get('news_id')
    comment_info = request.json.get('comment')
    parent_id = request.json.get('parent_id')
    # 3.校验参数
    if not all([news_id, comment_info]):
        return jsonify(errno=response_code.RET.PARAMERR, errmag='参数不全')
    # 3.1 判断参数类型是否正确
    try:
        news_id = int(news_id)
        if parent_id:
            parent_id = int(parent_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=response_code.RET.PARAMERR, errmag='参数错误')
    # 3.2 判断新闻是否存在
    try:
        news_info = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=response_code.RET.DBERR, errmag='新闻查询失败')
    if not news_info:
       return jsonify(errno=response_code.RET.DATAERR, errmag='无此新闻')

    # 4.创建模型对象
    comment = Comment()
    comment.user_id = user.id
    comment.news_id = news_id
    comment.content = comment_info
    if parent_id:
        comment.parent_id = parent_id
    try:
        db.session.add(comment)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=response_code.RET.DBERR, errmag='评论失败')

    # 为了在评论后刷新出评论的内容，需要响应给用户
    data = {
        'comment': comment.to_dict()
    }
    # 5.返回结果
    return jsonify(errno=response_code.RET.OK, errmag='评论成功', **data)



# 收藏与取消收藏
@news_blue.route('/news_collect', methods=['POST'])
@user_login_data
def news_collect():
    # 1.判断用户是否登陆
    user = g.user
    if not user:
        return jsonify(errno=response_code.RET.SESSIONERR, errmag='用户未登陆')
    json_data = request.json
    # 2.获取参数
    news_id = json_data.get("news_id")
    action = json_data.get("action")
    # 3.校验参数
    if not all([news_id, action]):
        return jsonify(errno=response_code.RET.PARAMERR, errmag='参数不全')
    if action not in ("collect", "cancel_collect"):
        return jsonify(errno=response_code.RET.DATAERR, errmag='参数错误')
    # 4.查询信息
    try:
        news_info = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=response_code.RET.DBERR, errmag='查询新闻数据失败')
    if not news_info:
        return jsonify(errno=response_code.RET.DATAERR, errmag='新闻数据不存在')
    if action == "collect":
        if news_info not in user.collection_news:
            user.collection_news.append(news_info)
    else:
        if news_info in user.collection_news:
            user.collection_news.remove(news_info)
    # 4.1操作数据库之后要提交数据
    # 此时没有新建对象，不需要add
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=response_code.RET.DBERR, errmag='操作数据失败')

    # 5.返回查询结果
    return jsonify(errno=response_code.RET.OK, errmag='操作数据成功')



# 用户详情页
@news_blue.route('/detail/<int:news_id>')
@user_login_data
def detail(news_id):
    # 1.获取用户是否登陆
    user = g.user
    # 2.获取点击排行
    try:
        news_clicks = News.query.order_by(News.clicks.desc()).limit(constants.CLICK_RANK_MAX_NEWS)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=response_code.RET.DBERR, errmag='查询数据库错误')
    # 3.通过拿到的news_id查询对应的真正的新闻信息
    news_data = None
    try:
        news_data = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)

    if not news_data:
        abort(404)
    news_info = news_data.to_dict()
    # 4.用户只有点击才会来这个视图，给对应的news.clicks加1
    news_data.clicks += 1
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
    # 5.判断用户是否有收藏该新闻，当然，前提是登陆的情况下
    is_collected = False
    if user:
        if news_data in user.collection_news:
            is_collected = True
    # 6.点赞功能的实现
    comment_id = []
    if user:
        try:
            comments = CommentLike.query.filter(CommentLike.user_id == user.id).all()
            comment_id = [comment.comment_id for comment in comments]
        except Exception as e:
            current_app.logger.error(e)

    comments = []
    for comment in news_data.comments.order_by(Comment.create_time.desc()):
        comment_info = comment.to_dict()
        comment_info['is_like'] = False
        comments.append(comment_info)
        if comment.id in comment_id:
            comment_info['is_like'] = True

    # 7.登陆用户关注新闻作者
    is_follower = False
    if user and news_data.user:
        if news_data.user in user.followed:
            is_follower = True


    # comments.sort(key=lambda x: x['create_time'], reverse=True)

    content = {
        "user": user.to_dict() if user else None,
        "news_clicks": news_clicks,
        "news_info": news_info,
        "is_collected": is_collected,
        "comment_list": comments,
        "is_follower": is_follower
    }
    print(comments)

    return render_template('news/detail.html', **content)
